package com.example.pm.service.impl;


import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.pm.common.constant.RedisConstant;
import com.example.pm.common.constant.SystemConstant;
import com.example.pm.common.redis.RedisUtils;
import com.example.pm.common.result.R;
import com.example.pm.common.utils.GzipUtils;
import com.example.pm.common.utils.StringUtils;
import com.example.pm.domain.Bo.PageBo;
import com.example.pm.domain.*;
import com.example.pm.domain.Model.EmployeeMenu;
import com.example.pm.domain.Model.UserPerm;
import com.example.pm.domain.Vo.PageVo;
import com.example.pm.mapper.*;
import com.example.pm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private GzipUtils gzipUtils;
    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private RoleMapper roleMapper;
    public static String status_disable = SystemConstant.USER_STATUS_DISABLE;
    public static String status_normal = SystemConstant.USER_STATUS_NORMAL;
    public static String EmptyZh = "00000000000";
    public static String redis_user = RedisConstant.getList_User;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private EmployeeMenuMapper employeeMenuMapper;
    @Autowired
    private PermMapper permMapper;
    @Autowired
    private UserPermMapper userPermMapper;


    @Override
    public PageVo<User> getUserPage(PageBo pageBo) {
//        List<User> users = userMapper.selectList(new LambdaQueryWrapper<>());
        List<User> users = (List<User>) redisUtils.get(redis_user);
        return new PageVo<>(pageBo, users);
    }


    @Override
    public R<Object> getUserBySearch(User user, PageBo pageBo) {
        String zh = user.getZh();
        String xm = user.getXm();
        if (StringUtils.isEmpty(zh) && StringUtils.isEmpty(xm)) return R.ok(this.getUserPage(pageBo));
        List<User> users = (List<User>) redisUtils.get(redis_user);
        List<User> userList = new ArrayList<>();
        if (StringUtils.isNotEmpty(zh)) {
            List<User> list = users.stream().filter(o -> StringUtils.isNotEmpty(o.getZh())).collect(Collectors.toList());
            userList.addAll(list.stream().filter(o -> zh.contains(o.getZh())).collect(Collectors.toList()));
            userList.addAll(list.stream().filter(o -> o.getZh().contains(zh)).collect(Collectors.toList()));
        }
        if (StringUtils.isNotEmpty(xm)) {
            List<User> list = users.stream().filter(o -> StringUtils.isNotEmpty(o.getXm())).collect(Collectors.toList());
            userList.addAll(list.stream().filter(o -> xm.contains(o.getXm())).collect(Collectors.toList()));
            userList.addAll(list.stream().filter(o -> o.getXm().contains(xm)).collect(Collectors.toList()));
        }
        userList = userList.stream().distinct().collect(Collectors.toList());
        PageVo<Object> vo = new PageVo<>(pageBo, userList);
        if (userList.isEmpty()) {
            return R.info("没有符合条件的数据", this.getUserPage(pageBo));
        }
        return R.ok(vo);
    }

    @Override
    public R<Object> changeZt(String zh, PageBo pageBo) {
        if (zh.equals(EmptyZh)) return R.fail("账号激活失败！失败原因未上传该员工的手机号码。");
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getZh, zh);
        List<User> users = userMapper.selectList(lqw);
        String zt;
        if (users.isEmpty()) {
            //账号表不存在此账号，现在添加账号
            zt = status_normal;
            this.createOneUser(zh);
            this.createUserPermList(zh);
        } else {
            //账号表存在此账号，现在禁用此账号
            zt = status_disable;
            users.stream().peek(o -> {
                o.setZt(status_disable);
                userMapper.updateById(o);
            }).collect(Collectors.toList());
            //删除此用户在员工菜单表中的数据（sys_employee_menu）
            LambdaQueryWrapper<EmployeeMenu> lqw_EM = new LambdaQueryWrapper<>();
            lqw_EM.eq(EmployeeMenu::getZh, zh);
            employeeMenuMapper.delete(lqw_EM);
            //删除此用户在账号权限表中的数据（sys_user_perm）
            LambdaQueryWrapper<UserPerm> lqw_UP = new LambdaQueryWrapper<>();
            lqw_UP.eq(UserPerm::getZh, zh);
            userPermMapper.delete(lqw_UP);
        }
        this.createUserRedis();

        return R.ok("账号" + zh + " ," + zt + "成功", getUserPage(pageBo));
    }

    @Override
    public byte[] getUserImage() {
        String zh = (String) StpUtil.getLoginId();
        String image = imageMapper.getImageByZh(zh);
        return gzipUtils.compress(image);
    }

    @Override
    public Map<String, Object> getInfo() {
        Map<String, Object> map = new HashMap<>();

        String zh = (String) StpUtil.getLoginId();
        Employee employee = employeeMapper.getByZh(zh);
        map.put("xm", employee.getXm());

        Role role = roleMapper.getByZh(zh);
        map.put("jsmc", role.getName());

        LambdaQueryWrapper<Login> lqw_login = new LambdaQueryWrapper<>();
        lqw_login.eq(Login::getAccount, zh);
        lqw_login.orderByDesc(Login::getTime);
        lqw_login.last("limit 1");
        Login login = loginMapper.selectOne(lqw_login);

        map.put("time", login.getTime().toString().replace("T", " "));
        map.put("ip", login.getIp());
        map.put("image", getUserImage());
        return map;
    }

    public void createOneUser(String zh) {
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Employee::getSjh, zh);
        Employee employee = employeeMapper.selectOne(lqw);
        Integer image_id = imageMapper.selectList(new LambdaQueryWrapper<>()).get(0).getId();
        Integer ptyg_id = roleMapper.selectList(new LambdaQueryWrapper<>()).stream().sorted(Comparator.comparing(Role::getAccess).reversed()).collect(Collectors.toList()).get(0).getId();
        String sjh = employee.getSjh();

        User user = new User();
        user.setZh(sjh);
        user.setYz(SaFoxUtil.getRandomString(10));
        user.setMm(SaSecureUtil.sha256(sjh.substring(Math.max(sjh.length() - 4, 0)) + user.getYz()));
        user.setZt(status_normal);
        user.setEmployeeId(employee.getId());
        user.setImageId(image_id);
        user.setRoleId(ptyg_id);
        user.setXm(employee.getXm());

        userMapper.insertUser(user);
    }

    //创建初始账号数据
    @Override
    public void createUserRedis() {
        //删除禁用账号
        LambdaQueryWrapper<User> lqw_user = new LambdaQueryWrapper<>();
        lqw_user.eq(User::getZt, status_disable);
        userMapper.delete(lqw_user);
        //获取所有账号
        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<>());
        //将无用项设置为空
        userList = userList.stream().peek(o -> {
            o.setMm(null);
            o.setYz(null);
            o.setRoleId(null);
            o.setImage(null);
            o.setImageId(null);
            o.setEmployeeId(null);
        }).collect(Collectors.toList());
        //提取账号列表的手机号码
        List<String> ZhangHao = userList.stream().map(User::getZh).collect(Collectors.toList());
        //获取所有员工，并将未填写手机号的员工手机号设置为统一的空账号
        List<Employee> employeeList = employeeMapper.selectList(new LambdaQueryWrapper<>());
        employeeList = employeeList.stream().peek(o -> {
            if (StringUtils.isEmpty(o.getSjh())) o.setSjh(EmptyZh);
        }).collect(Collectors.toList());
        //筛选出未生成账号的员工
        employeeList = employeeList.stream().filter(o -> !ZhangHao.contains(o.getSjh())).collect(Collectors.toList());
        //给这些员工生成账号信息
        List<User> users = employeeList.stream().map(o -> {
            User user = new User();
            String sjh = o.getSjh();
            user.setZh(sjh);
            user.setZt(status_disable);
            user.setXm(o.getXm());
            return user;
        }).collect(Collectors.toList());

        userList.addAll(users);
        //生成缓存
        redisUtils.set(redis_user, userList, RedisConstant.getList_User_Time);
    }

    @Override
    public R<String> changeRole(User user) {
        userMapper.updateById(user);
        this.createUserPermList(user.getZh());
        return R.ok("操作成功");
    }

    //为账户创建权限
    @Async
    public void createUserPermList(String zh) {
        LambdaQueryWrapper<UserPerm> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserPerm::getZh, zh);
        userPermMapper.delete(lqw);

        List<Perm> perms = permMapper.selectList(new LambdaQueryWrapper<>());

        Integer access = roleMapper.getByZh(zh).getAccess();

        List<UserPerm> list = perms.stream().filter(o -> o.getJsjb() >= access).map(o -> {
            UserPerm userPerm = new UserPerm();
            userPerm.setZh(zh);
            userPerm.setPerm(o.getPerm());
            return userPerm;
        }).collect(Collectors.toList());

        userPermMapper.insertList(list);
    }
}
